home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0027_Another B-Spline Curve.pas < prev    next >
Pascal/Delphi Source File  |  1993-08-27  |  4KB  |  175 lines

  1. {
  2. SEAN PALMER
  3.  
  4. I've been playing around with it as a way to make 'heat-seeking
  5. missiles' in games. Very interesting...
  6.  
  7. What I do is have the points set up as follows:
  8.  
  9. 1   : current position
  10. 2&3 : current speed + the current position
  11. 4   : destination
  12.  
  13. and update current position by indexing somewhere into the curve (like
  14. at $100 out of $FFFF
  15.  
  16. This works very well. Problem is that I don't know of a good way to
  17. change the speed.
  18.  
  19. Here is a simple demo that makes a dot chase the mouse cursor (needs
  20. VGA as written) that shows what I mean.
  21.  
  22. If ANYBODY can make this work smoother or improve on it in any way I
  23. would appreciate being told how... 8)
  24. }
  25.  
  26. uses
  27.   mouse, crt;  { you will need to change accesses to the mouse unit }
  28.                { to use a mouse package that you provide }
  29. type
  30.   coord = record
  31.     x, y : word;
  32.   end;
  33.   CurveDataRec = array [0..65521 div sizeof(coord)] of coord;
  34.  
  35. const
  36.   nSteps = 1 shl 8;  {about 8 for smoothness (dots), 4 for speed (lines)}
  37.  
  38. var
  39.   color : byte;
  40.   src, spd,
  41.   dst, mov1,
  42.   mov2 : coord;
  43.   i : integer;
  44.  
  45. procedure plot(x, y : word);
  46. begin
  47.   mem[$A000 : y * 320 + x] := color;
  48. end;
  49.  
  50. function fracMul(f, f2 : word) : word;
  51. Inline(
  52.   $58/                   {pop ax}
  53.   $5B/                   {pop bx}
  54.   $F7/$E3/               {mul bx}
  55.   $89/$D0);              {mov ax,dx}
  56.  
  57. function mul(f, f2 : word) : longint;
  58. inline(
  59.   $58/                   {pop ax}
  60.   $5B/                   {pop bx}
  61.   $F7/$E3);              {mul bx}
  62.  
  63.  
  64. {this is the original full BSpline routine}
  65.  
  66. procedure drawBSpline(var d0 : coord; nPoints : word);
  67. const
  68.   nsa  = $10000 div 6;
  69.   nsb  = $20000 div 3;
  70.   step = $10000 div nSteps;
  71. var
  72.   i, xx, yy : word;
  73.   t1, t2, t3 : word;
  74.   c1, c2, c3, c4 : word;
  75.   d : curveDataRec absolute d0;
  76. begin
  77.   t1 := 0;
  78.   color := 32 + 2;
  79.   for i := 0 to nPoints - 4 do
  80.   begin
  81.     {algorithm converted from Steve Enns' original Basic subroutine}
  82.     repeat
  83.       t2 := fracMul(t1, t1);
  84.       t3 := fracMul(t2, t1);
  85.       c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
  86.       c2 := (t3 shr 1) + nsb - t2;
  87.       c3 := ((t2 + t1 - t3) shr 1) + nsa;
  88.       c4 := fracmul(nsa, t3);
  89.       xx := (mul(c1, d[i].x) + mul(c2, d[i + 1].x) +
  90.              mul(c3, d[i + 2].x) + mul(c4, d[i + 3].x)) shr 16;
  91.       yy := (mul(c1, d[i].y) + mul(c2, d[i + 1].y) +
  92.              mul(c3, d[i + 2].y) + mul(c4, d[i + 3].y)) shr 16;
  93.       plot(xx, yy);
  94.       inc(t1, step);
  95.     until t1 = 0;  {this is why nSteps must be even power of 2}
  96.     inc(color);
  97.   end;
  98. end;
  99.  
  100.  
  101. {find 1/nth point in BSpline}  {this is what does the B-Spline work}
  102.  
  103. procedure moveTowards(d1, d2, d3, d4 : coord; t1 : word; var mov : coord);
  104. const
  105.   nsa = $10000 div 6;
  106.   nsb = $20000 div 3;
  107. var
  108.   t2, t3 : word;
  109.   c1, c2,
  110.   c3, c4 : word;
  111. begin
  112.   t2 := fracMul(t1, t1);
  113.   t3 := fracMul(t2, t1);
  114.   c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
  115.   c2 := (t3 shr 1) + nsb - t2;
  116.   c3 := ((t2 + t1 - t3) shr 1) + nsa;
  117.   c4 := fracmul(nsa, t3);
  118.   mov.x := (mul(c1, d1.x) + mul(c2, d2.x) + mul(c3, d3.x) + mul(c4, d4.x)) shr 16;
  119.   mov.y := (mul(c1, d1.y) + mul(c2, d2.y) + mul(c3, d3.y) + mul(c4, d4.y)) shr 16;
  120. end;
  121.  
  122. begin
  123.   asm
  124.     mov ax, $13
  125.     int $10
  126.   end;  {init vga/mcga graphics}
  127.  
  128.   {mouse.init;}
  129.   mshow;
  130.  
  131.   src.x := 5;
  132.   src.y := 5;
  133.   spd.x := 5;
  134.   spd.y := 5;
  135.   dst.x := 315;
  136.   dst.y := 190;
  137.  
  138.   repeat
  139.    {for i:=0 to 23 do begin}
  140.    { color:=i+32;}
  141.    { inc(dst.x,i);}
  142.     delay(10);
  143.     {mouse.check;}  {this loads Mouse.X, Mouse.Y, Mouse.Button from driver}
  144.     mhide;
  145.     color := 15;
  146.     plot(src.x, src.y);
  147.     color := 14;
  148.     plot(spd.x, spd.y);
  149.     dst.x := mousex shr 1;
  150.     dst.y := mousey;
  151.     color := 1;
  152.     plot(dst.x, dst.y);
  153.     mshow;
  154.  
  155.     {the parameters in these next two lines can be changed}
  156.     {I have played with almost all possible combinations and}
  157.     {most work, but not well, so don't be afraid to play around}
  158.     {But I think an entirely different approach is needed for the}
  159.     {second moveTowards..}
  160.  
  161.     moveTowards(src, src, spd, dst, $0010, mov1);
  162.     moveTowards(src, spd, dst, dst, $5000, mov2);
  163.     src := mov1;
  164.     longint(spd) := (longint(spd) * 7 + longint(mov2)) shr 3 and $1FFF1FFF;
  165.   until 1=0;
  166.  
  167.   mhide;
  168.  
  169.   asm
  170.     mov ax, 3
  171.     int $10
  172.   end; {text mode again}
  173. end.
  174.  
  175.